package org.despair2D.ui.puppet 
{
	import flash.display.DisplayObject;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import org.despair2D.debug.Logger;
	import org.despair2D.renderer.AnimeBase;
	import org.despair2D.ui.core.UIManager;
	import org.despair2D.ui.events.ManipulateEvent;
	import org.despair2D.ui.events.VisibleEvent;
	import org.despair2D.ui.Fusion;
	import org.despair2D.ui.DespairUI;
	
	import org.despair2D.core.ns_despair;
	use namespace ns_despair;
	
	
	[Event(name = "press", type = "org.despair2D.ui.events.ManipulateEvent")] 
	
	[Event(name = "release", type = "org.despair2D.ui.events.ManipulateEvent")] 
	
	[Event(name = "over", type = "org.despair2D.ui.events.ManipulateEvent")] 
	
	[Event(name = "leave", type = "org.despair2D.ui.events.ManipulateEvent")] 
	
	[Event(name = "move", type = "org.despair2D.ui.events.ManipulateEvent")] 
	
	[Event(name = "click", type = "org.despair2D.ui.events.ManipulateEvent")] 
	
	[Event(name = "doubleClick", type = "org.despair2D.ui.events.ManipulateEvent")] 
		
	
	[Event(name = "startDrag", type = "org.despair2D.ui.events.ManipulateEvent")] 
	
	[Event(name = "stopDrag", type = "org.despair2D.ui.events.ManipulateEvent")] 

	[Event(name = "killed", type = "org.despair2D.ui.events.ManipulateEvent")] 
	
	[Event(name = "interactiveChange", type = "org.despair2D.ui.events.InteractiveEvent")] 
	
	[Event(name = "visibleChange", type = "org.despair2D.ui.events.VisibleEvent")] 
	
	
final public class AnimePuppet extends AnimeBase implements IPuppet
{
	
	public function AnimePuppet()
	{
		m_view = new AnimePuppetComp(this)
	}
	
	
	
	final public function get name () : String { return m_view.name;  }
	final public function set name ( v:String ) : void 
	{
		m_view.name = v;
	}
	
	final public function get x () : Number { return m_view.x; }
	final public function set x ( v:Number ) : void 
	{
		m_view.x = v;
	}
	
	final public function get y () : Number { return m_view.y; }
	final public function set y ( v:Number ) : void 
	{
		m_view.y = v;
	}

	
	final public function get mouseX () : Number { return m_view.mouseX; }
	final public function get mouseY () : Number { return m_view.mouseY; }
	
	final public function get width() : Number { return m_width * m_view.m_scaleX; }
	final public function set width( v:Number ) : void
	{
		m_view.scaleX = v / m_width
	}
	
	final public function get height () : Number { return m_height * m_view.m_scaleY; }
	final public function set height( v:Number ) : void
	{
		m_view.scaleY = v / m_height
	}
	

	final public function get rotation () : Number { return m_view.rotation; }
	final public function set rotation ( v:Number ) : void 
	{
		m_view.rotation = v;
	}
	
	
	final public function get scaleX () : Number { return m_view.scaleX; }
	final public function set scaleX ( v:Number ) : void 
	{
		m_view.scaleX = v;
	}
	
	
	final public function get scaleY () : Number { return m_view.scaleY; }
	final public function set scaleY ( v:Number ) : void 
	{
		m_view.scaleY = v;
	}
	
	final public function get alpha () : Number { return m_view.alpha; }
	final public function set alpha ( v:Number ):void 
	{
		m_view.alpha = v;
	}
	
	final public function get visible () : Boolean { return m_view.visible; }
	final public function set visible ( b:Boolean ) : void 
	{
		m_view.visible = b;
		this.paused = !b;
	}
	

	final public function get filters () : Array { return m_view.filters; }
	final public function set filters ( v:Array ) : void 
	{
		m_view.filters = v;
	}
	
	
	final public function get interactive () : Boolean { return m_view.interactive; }
	final public function set interactive ( b:Boolean ) : void 
	{
		m_view.interactive = b;
	}
	
	
	
	
	

	final public function get fusion() : Fusion
	{
		return m_view.fusion;
	}
	
	final public function get displayObject() : DisplayObject
	{
		return m_view
	}
	
	final public function get globalPos() : Point
	{
		return m_view.globalPos
	}
	
	final public function get layer() : int
	{
		return m_view.layer
	}
	
	final public function get hovered() : Boolean
	{
		return Boolean(DespairUI.overPuppet == this);
	}
	
	final public function get pressed() : Boolean
	{
		return Boolean(DespairUI.pressedPuppet == this);;
	}
	
	public function get dragging() : Boolean
	{
		return Boolean(DespairUI.draggingObject == this)
	}
	
	final public function get draggingInBounds() : Boolean
	{
		return Boolean(DespairUI.draggingObject == this && UIManager.m_draggingInBounds)
	}
	
	
	final public function get userData() : Object { return m_userData; }
	public function set userData( v:Object ) : void
	{
		m_userData = v;
	}
	
	
	
	
	final public function move( px:Number, py:Number ) : void
	{
		m_view.move(px, py);
	}
	
	
	final public function moveInStage( px:Number, py:Number ) : void
	{
		m_view.moveInStage(px, py)
	}
	
	
	final public function offset( tx:Number, ty:Number ) : void
	{
		m_view.offset(tx, ty);
	}
	
	
	final public function startDrag( lockCenter:Boolean = false, bounds:Rectangle = null ) : void
	{
		UIManager.startDragComp(this.m_view, lockCenter, bounds);
	}
	
	
	final public function kill() : void
	{
		m_view.m_fusion.removePuppet(this);
		this.recycle();
	}
	
	
	
	
	final public function addEventListener ( type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false ) : void
	{
		m_view.addEventListener(type, listener, useCapture, priority, useWeakReference);
	}
	
	
	final public function dispatchEvent ( event:Event ) : Boolean
	{
		return m_view.dispatchEvent(event);
	}
	

	final public function hasEventListener ( type:String ) : Boolean
	{
		return m_view.hasEventListener(type);
	}
	

	final public function removeEventListener ( type:String, listener:Function, useCapture:Boolean = false ) : void
	{
		m_view.removeEventListener(type, listener, useCapture);
	}
	
	
	final public function willTrigger ( type:String ) : Boolean
	{
		return m_view.willTrigger(type);
	}
	
	
	final public function removeAllEventListeners() : void
	{
		m_view.removeAllEventListeners()
	}
	
	
	
	//======================
	// Internal
	//======================
	
	
	final override ns_despair function _setNullSection() : void
	{
		m_view.addToModifyList();
		m_view.m_flags |=  AnimePuppetComp.c_nullFlag
	}
	
	
	final override ns_despair function _makeImageDirty():void
	{
		m_view.addToModifyList();
	}
	
	
	final override ns_despair function recycle() : void
	{
		super.recycle();
		m_view.recycle();
		
		cachedAnimePuppetList[cachedAnimePuppetLength++] = this;
	}

	
	ns_despair static function getAnimePuppet( sectionName:String ) : AnimePuppet
	{
		var A:AnimePuppet = (cachedAnimePuppetLength > 0 ? cachedAnimePuppetLength-- : 0) ? cachedAnimePuppetList.pop() : new AnimePuppet();
		A.section = sectionName
		
		// [visible改变]时，[暂停/恢复]自动化...
		A.addEventListener(VisibleEvent.VISIBLE_CHANGE, ____onVisibleChange)
		return A;
	}
	
	
	ns_despair static function ____onVisibleChange( e:VisibleEvent ) : void
	{
		(e.target as AnimePuppet).paused = !e.visible
	}
	
	
	
	
	//======================
	// Member
	//======================
	
	
	ns_despair static var cachedAnimePuppetList:Array = [];
	
	ns_despair static var cachedAnimePuppetLength:int;
	
	ns_despair static var m_animeSpeed:Number = 1;
	
	
	ns_despair var m_view:AnimePuppetComp;
	
	ns_despair var m_userData:Object

}

}

import org.despair2D.renderer.sections.BitmapInfo;
import org.despair2D.ui.puppet.IPuppet
import org.despair2D.ui.puppet.AnimePuppet
import org.despair2D.ui.puppet.PuppetCompBase
import org.despair2D.ui.puppet.ModifiableImagePuppetComp

import org.despair2D.core.ns_despair;
use namespace ns_despair;
	
	
final class AnimePuppetComp extends ModifiableImagePuppetComp
{
	
	public function AnimePuppetComp( proxy:IPuppet )
	{
		super(proxy);
	}
	
	
	/* 画像消失 */
	ns_despair static const c_nullFlag:uint = 0x20;
	
	
	
	final override public function modify() : void
	{
		var proxy:AnimePuppet
		var bitmapInfo:BitmapInfo
		
		if (m_flags & c_nullFlag)
		{
			m_img.bitmapData = null;
		}
		
		else
		{
			proxy                 =  m_proxy as AnimePuppet
			bitmapInfo            =  proxy.m_section.getBitmapInfoByPointer(proxy.m_pointer);
			m_img.x               =  bitmapInfo.tx + proxy.m_x;
			m_img.y               =  bitmapInfo.ty + proxy.m_y;
			m_img.bitmapData      =  bitmapInfo.bmd;
			this.m_img.smoothing  =  m_transformDirty;
		}
		
		m_flags &= ~0xF0;
	}

}
